package com.mastercard.assets.web.listener;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Timer;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.mastercard.assets.jpa.TblFileRespaldo;
import com.mastercard.assets.jpa.TblFormaRespaldo;
import com.mastercard.assets.util.MCUtil;
import com.mastercard.assets.util.dao.MasterCardDAO;
import com.mastercard.assets.web.robot.MasterCardDayRobot;
import com.mastercard.assets.web.robot.MasterCardHourRobot;

/**
 * Application Lifecycle Listener implementation class MasterCardApplicationListener
 *
 */
public class MasterCardApplicationListener
	implements
		ServletContextListener
{
	/**
	 * 	Robot a ejecutarse cada dia.
	 */
	private MasterCardDayRobot robotDay ;
	
	/**
	 * 	Robot a ejecutarse cada hora.
	 */
	private MasterCardDayRobot robotHour ;
	
	/**
	 * 	Timer para el robot por horas.
	 */
	private Timer timer ;

    /**
     * Default constructor. 
     */
    public MasterCardApplicationListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized( ServletContextEvent arg0 )
    {
		try
		{
//			EntityManagerFactory emf = Persistence.createEntityManagerFactory( "MasterCardJPA" ) ;
//		
//			EntityManager em = emf.createEntityManager( ) ;
//			
//			MasterCardDAO.init( em ) ;
                        
                        MCUtil.intiPasswordSecurity( ) ;
			
			// levanta las propiedades del sistema
			MCUtil.WEB_INF_DIR = arg0.getServletContext( ).getRealPath( "/WEB-INF/" ) + System.getProperty( "file.separator" ) ;
			
			System.out.println( MCUtil.WEB_INF_DIR ) ;
			
			MCUtil.SYSTEM_PROPERTIES.load( new FileInputStream( MCUtil.WEB_INF_DIR + System.getProperty( "file.separator" ) + "system.properties" ) ) ;
			
			// lee las propiedades
			String bcInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "bc.directorio.inside" ) ;
			String bcDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "bc.directorio" ) ;
//			System.out.println( bcDir ) ;
//			System.out.println( System.getProperty( "file.separator" ) ) ;
			String replace = "" ;
			if( System.getProperty( "file.separator" ).equals( "/" ) )
				replace = System.getProperty( "file.separator" ) ;
			else
				replace = System.getProperty( "file.separator" ) + System.getProperty( "file.separator" ) ;
			bcDir = bcDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( bcInside == null || bcInside.equals( "1" ) )
//				MCUtil.BC_DIR = MCUtil.WEB_INF_DIR + ( ( bcDir != null ) ? bcDir : "bc" ) + System.getProperty( "file.separator" ) ;
				MCUtil.BC_DIR = "/WEB-INF/" + ( ( bcDir != null ) ? bcDir : "bc" ) + "/" ;
			else
				MCUtil.BC_DIR = ( ( bcDir != null ) ? bcDir : System.getProperty( "file.separator" ) + "bc" ) + System.getProperty( "file.separator" ) ;
			
//			File f = new File( MCUtil.BC_DIR ) ;
			File f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.BC_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
			
			String formasInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "formas.directorio.inside" ) ;
			String formasDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "formas.directorio" ) ;
			formasDir = formasDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( formasInside == null || formasInside.equals( "1" ) )
				MCUtil.FORMAS_DIR = "/WEB-INF/" + ( ( formasDir != null ) ? formasDir : "formas" ) + "/" ;
			else
				MCUtil.FORMAS_DIR = ( ( formasDir != null ) ? formasDir : System.getProperty( "file.separator" ) + "formas" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.FORMAS_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
                        
                        //werty
                        String contratoInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "contrato.directorio.inside" ) ;
			String contratoDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "contrato.directorio" ) ;
			contratoDir = contratoDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( contratoInside == null || contratoInside.equals( "1" ) )
				MCUtil.CONTRATO_DIR = "/WEB-INF/" + ( ( contratoDir != null ) ? contratoDir : "contrato" ) + "/" ;
			else
				MCUtil.CONTRATO_DIR = ( ( contratoDir != null ) ? contratoDir : System.getProperty( "file.separator" ) + "contrato" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.CONTRATO_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
                        
                        //werty
                        String fotosInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "fotos.directorio.inside" ) ;
			String fotosDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "fotos.directorio" ) ;
			contratoDir = fotosDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( fotosInside == null || fotosInside.equals( "1" ) )
				MCUtil.FOTOS_DIR = "/WEB-INF/" + ( ( fotosDir != null ) ? fotosDir : "fotos" ) + "/" ;
			else
				MCUtil.FOTOS_DIR = ( ( fotosDir != null ) ? fotosDir : System.getProperty( "file.separator" ) + "contrato" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.FOTOS_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
                        
                        //werty
                        String boletoInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "boleto.directorio.inside" ) ;
			String boletoDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "boleto.directorio" ) ;
			boletoDir = boletoDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( boletoInside == null || boletoInside.equals( "1" ) )
				MCUtil.BOLETO_DIR = "/WEB-INF/" + ( ( boletoDir != null ) ? boletoDir : "boleto" ) + "/" ;
			else
				MCUtil.BOLETO_DIR = ( ( boletoDir != null ) ? boletoDir : System.getProperty( "file.separator" ) + "boleto" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.BOLETO_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;                        
                        
                        //werty
                        String agendaInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "agenda.directorio.inside" ) ;
			String agendaDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "agenda.directorio" ) ;
			agendaDir = agendaDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( agendaInside == null || agendaInside.equals( "1" ) )
				MCUtil.AGENDA_DIR = "/WEB-INF/" + ( ( agendaDir != null ) ? agendaDir : "agenda" ) + "/" ;
			else
				MCUtil.AGENDA_DIR = ( ( agendaDir != null ) ? agendaDir : System.getProperty( "file.separator" ) + "agenda" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.AGENDA_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
                        
                        //werty
                        String cotizacionInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "cotizacion.directorio.inside" ) ;
			String cotizacionDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "cotizacion.directorio" ) ;
			cotizacionDir = cotizacionDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( cotizacionInside == null || cotizacionInside.equals( "1" ) )
				MCUtil.COTIZACION_DIR = "/WEB-INF/" + ( ( cotizacionDir != null ) ? cotizacionDir : "cotizacion" ) + "/" ;
			else
				MCUtil.COTIZACION_DIR = ( ( cotizacionDir != null ) ? cotizacionDir : System.getProperty( "file.separator" ) + "cotizacion" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.COTIZACION_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
                        
                        //werty
                        String materialdeassetInside = MCUtil.SYSTEM_PROPERTIES.getProperty( "materialdeasset.directorio.inside" ) ;
			String materialdeassetDir = MCUtil.SYSTEM_PROPERTIES.getProperty( "materialdeasset.directorio" ) ;
			materialdeassetDir = materialdeassetDir.replaceAll( "/" , replace ).replaceAll( "\\\\" , replace ) ;
			
			// en caso de inside
			if( materialdeassetInside == null || materialdeassetInside.equals( "1" ) )
				MCUtil.MATERIALASSET_DIR = "/WEB-INF/" + ( ( materialdeassetDir != null ) ? materialdeassetDir : "materialdeasset" ) + "/" ;
			else
				MCUtil.MATERIALASSET_DIR = ( ( materialdeassetDir != null ) ? materialdeassetDir : System.getProperty( "file.separator" ) + "materialdeasset" ) + System.getProperty( "file.separator" ) ;
			
			f = new File( arg0.getServletContext( ).getRealPath( "/" ) + MCUtil.MATERIALASSET_DIR ) ;
			
			// en caso de que no exista
			if( ! f.exists( ) )
				f.mkdirs( ) ;
			
			// toma los respaldos
			List< TblFormaRespaldo > formas = MasterCardDAO.getAllFormBackup( ) ;
			
			String formsDir = MCUtil.getFormsDir( ) ;
			File dir = new File( formsDir ) ;
			
			// los recorre
			for( TblFormaRespaldo r : formas )
			{
				// toma los datos
				String name = r.getName( ) ;
				
				System.out.println( r.getContent( ).getClass( ) ) ;
				
				byte[ ] content = r.getContent( ).getBytes( ) ;
				
				// lo guarda en el directorio de formas
				File fForm = new File( formsDir , name ) ;
				
				System.out.println( "Archivo a guardar: " + fForm.getAbsolutePath( ) ) ;
				
				// abre archivo
				FileOutputStream out = new FileOutputStream( fForm ) ;
				
				// guarda contenido
				out.write( content ) ;
				
				// cierra
				out.close( ) ;
				
				// borra registro
				MasterCardDAO.dropFormBackup( r ) ;
			}
			
			// toma los respaldos
			List< TblFileRespaldo > files = MasterCardDAO.getAllFileBackup( ) ;
			
			// los recorre
			for( TblFileRespaldo r : files )
			{
				String filesDir = r.getDirectory( ) ;
				int insideApp = r.getInsideApp( ) ;
				
				dir = null ;
				
				// dentro de la aplicacion
				if( insideApp == 1 )
					dir = new File( arg0.getServletContext( ).getRealPath( "/" ) + filesDir ) ;
				else
					dir = new File( filesDir ) ;
				
				// toma los datos
				String name = r.getName( ) ;
				
				byte[ ] content = r.getContent( ).getBytes( ) ;
				
				// lo guarda en el directorio de formas
//				File fForm = new File( filesDir , name ) ;
				File fForm = new File( new File( arg0.getServletContext( ).getRealPath( "/WEB-INF/bc" ) ) , name ) ;
				
				System.out.println( "Archivo a guardar: " + fForm.getAbsolutePath( ) ) ;
				
				// abre archivo
				FileOutputStream out = new FileOutputStream( fForm ) ;
				
				// guarda contenido
				out.write( content ) ;
				
				// cierra
				out.close( ) ;
				
				// borra registro
				MasterCardDAO.dropFileBackup( r ) ;
			}
			
			MasterCardHourRobot robotHour = new MasterCardHourRobot( ) ;
			robotDay = new MasterCardDayRobot( ) ;
			
	    	System.out.println( "Se prepara para generar el robot" ) ;
			timer = new Timer( ) ;
			
			// lo hace cada hora
			GregorianCalendar gc = new GregorianCalendar( ) ;
			
			System.out.println( "Time Hoy: " + gc.getTimeInMillis( ) ) ;
			System.out.println( "Time Hoy: " + gc.getGregorianChange( ) ) ;
			
			// coloca minutos en 0
			gc.set( Calendar.MILLISECOND , 0 ) ;
			gc.set( Calendar.MINUTE , 0 ) ;
			gc.set( Calendar.SECOND , 0 ) ;
			gc.add( Calendar.HOUR , 1 ) ;
			
			System.out.println( "Time Hoy: " + gc.getTimeInMillis( ) ) ;
			System.out.println( "Time Hoy: " + gc.getGregorianChange( ) ) ;
			System.out.println( "Time Hoy: " + new Date( gc.getTimeInMillis( ) ) ) ;
			
			// empieza en la hora indicada, y el tiempo de separacion es cada hora
			long hourInMillis = 1000L * 60L * 60L ;
			long dayInMillis = 1000L * 60L * 60L * 24L ;
			timer.scheduleAtFixedRate( robotHour , new Date( gc.getTimeInMillis( ) ) , hourInMillis ) ;
	    	System.out.println( "Robot inicializado por hora" ) ;
			
	    	gc = new GregorianCalendar( ) ;

			// coloca minutos en 0
			gc.set( Calendar.MILLISECOND , 0 ) ;
			gc.set( Calendar.SECOND , 0 ) ;
			gc.set( Calendar.MINUTE , 0 ) ;
			gc.set( Calendar.HOUR , 0 ) ;
			gc.add( Calendar.DATE , 1 ) ;
			
			System.out.println( new Date( gc.getTimeInMillis( ) ) ) ;
			
			timer.scheduleAtFixedRate( robotDay , new Date( gc.getTimeInMillis( ) ) , dayInMillis ) ;
	    	System.out.println( "Robot inicializado por dia" ) ;
	    	MasterCardDAO.closeEntityManager( ) ;
//	    	MCUtil.sendMail( "gumer_mexico@hotmail.com" , "hola mundo" , "Estamos probando" ) ;
		}catch( Exception e )
		{
                    MasterCardDAO.closeEntityManager( ) ;
			e.printStackTrace( ) ;
		}
                MasterCardDAO.closeEntityManager( ) ;
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed( ServletContextEvent arg0 )
    {
		System.out.println( "------- Destruccion del contexto ---------" ) ;
		// respalda las formas
		// toma el directorio
		String formsDir = MCUtil.getFormsDir( ) ;
		System.out.println( "Directorio de formas: " + formsDir ) ;
		// crea el directorio en File
		File dir = new File( formsDir ) ;
		
		// toma los files internos
		File[ ] files = dir.listFiles( ) ;
		
		System.out.println( "Resultado de archivos: " + files ) ;
		
		// en caso de que no sea null
		if( files != null )
		{
			// recorre
			for( File f : files )
			{
				try
				{
					// abre archivo
					FileInputStream in = new FileInputStream( f ) ;
					
					// lee
					byte[ ] read = new byte[ in.available( ) ] ;
					
					in.read( read ) ;
					
					// cierra
					in.close( ) ;
					
					System.out.println( "Nombre del archivo a guardar: " + f.getName( ) ) ;
					
					// guarda en la bd
					MasterCardDAO.saveFormBackup( f.getName( ) , new String( read ) ) ;
					
					// borra el archivo
					boolean res = f.delete( ) ;
					
					System.out.println( "Borro: " + res ) ;
					
				}catch( Exception e )
				{
                                    MasterCardDAO.closeEntityManager( ) ;
					System.out.println( "Error al guardar el archivo [" + f.getName( ) + "]: " + e.getMessage( ) ) ;
				}
			}
		}
		
		// respalda los archivos del directorio /WEB-BC
		// toma el directorio
		String filesDir = arg0.getServletContext( ).getRealPath( "/WEB-INF/bc" ) ;
		System.out.println( "Directorio de formas: " + filesDir ) ;
		// crea el directorio en File
		dir = new File( filesDir ) ;
		
		// toma los files internos
		files = dir.listFiles( ) ;
		
		System.out.println( "Resultado de archivos: " + files ) ;
		
		// en caso de que no sea null
		if( files != null )
		{
			// recorre
			for( File f : files )
			{
				try
				{
					// abre archivo
					FileInputStream in = new FileInputStream( f ) ;
					
					// lee
					byte[ ] read = new byte[ in.available( ) ] ;
					
					in.read( read ) ;
					
					// cierra
					in.close( ) ;
					
					System.out.println( "Nombre del archivo a guardar: " + f.getName( ) ) ;
					
					// guarda en la bd
					MasterCardDAO.saveFileBackup( "/WEB-INF/bc" , f.getName( ) , new String( read ) , 1 ) ;
					
					// borra el archivo
					boolean res = f.delete( ) ;
					
					System.out.println( "Borro: " + res ) ;
					
				}catch( Exception e )
				{
                                    MasterCardDAO.closeEntityManager( ) ;
					System.out.println( "Error al guardar el archivo [" + f.getName( ) + "]: " + e.getMessage( ) ) ;
				}
			}
		}
		
		System.out.println( "Se prepara para cancelar el robot" ) ;
		
		// cancela trabajos
//		robotHour.cancel( ) ;
//		robotDay.cancel( ) ;
		
		timer.cancel( ) ;
		
		System.out.println( "Robot cancelado" ) ;
		
		MasterCardDAO.closeEntityManager( ) ;
		System.out.println( "------- Destruccion del contexto Final ---------" ) ;
    }
	
}
